home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / jaq / dist / jls.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-05  |  15.3 KB  |  593 lines

  1. /* 
  2.  * jls.c --
  3.  *
  4.  *    Perform ls on Jaquith archive system.
  5.  *
  6.  * Copyright 1991 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  *
  15.  * Quote:
  16.  *      "Say the name."
  17.  *      -- Boris Badinov (Rocky & Bullwinkle show)
  18.  *
  19.  */
  20.  
  21. #ifndef lint
  22. static char rcsid[] = "$Header: /sprite/lib/forms/RCS/jls.c,v 1.0 91/01/07 18:02:37 mottsmth Exp $ SPRITE (Berkeley)";
  23. #endif /* not lint */
  24.  
  25. #include "jaquith.h"
  26. #include "option.h"
  27. #include "jlsInt.h"
  28.  
  29. int syserr;
  30.  
  31. static void  CheckOptions     _ARGS_ ((Parms *parmsPtr));
  32. static void  SendStrings      _ARGS_ ((int argc, char **argv, int sock));
  33. static void  ReadAndShowFiles _ARGS_ ((int sock, Parms *parmsPtr));
  34. static char *CvtModeToString  _ARGS_ ((int mode));
  35. static void  FormatRegular    _ARGS_ ((T_FileStat *statInfoPtr,
  36.                        Parms *parmsPtr,
  37.                        char *workingDir,
  38.                        int workingDirLen));
  39. static void  FormatRaw        _ARGS_ ((T_FileStat *statInfoPtr));
  40.  
  41. static char printBuf[T_MAXSTRINGLEN];
  42. static FILE *memDbg = NULL;
  43.  
  44. Parms parms = {
  45.     "",
  46.     -1,
  47.     "",
  48.     DEF_RANGE,
  49.     DEF_ASOF,
  50.     DEF_SINCE,
  51.     DEF_ABS,
  52.     DEF_OWNER,
  53.     DEF_GROUP,
  54.     DEF_SYNC,
  55.     DEF_MAIL,
  56.     DEF_RECURSE,
  57.     DEF_MODDATE,
  58.     DEF_ALL,
  59.     DEF_FIRSTVER,
  60.     DEF_LASTVER,
  61.     DEF_FIRSTDATE,
  62.     DEF_LASTDATE,
  63.     DEF_LPRINTFMT,
  64.     DEF_IPRINTFMT,
  65.     DEF_UPRINTFMT,
  66.     DEF_APRINTFMT,
  67.     DEF_SPRINTFMT,
  68.     DEF_GPRINTFMT,
  69.     DEF_DIRONLY,
  70.     DEF_RAW
  71. };
  72.  
  73. Option optionArray[] = {
  74.     {OPT_STRING, "server", (char *)&parms.server, "Server host"},
  75.     {OPT_INT, "port", (char *)&parms.port, "Port of server"},
  76.     {OPT_STRING, "arch", (char *)&parms.arch, "Logical archive name"},
  77.     {OPT_STRING, "range", (char *)&parms.range, "Date range"},
  78.     {OPT_STRING, "asof", (char *)&parms.asof, "Date specification"},
  79.     {OPT_STRING, "since", (char *)&parms.since, "Date specification"},
  80.     {OPT_STRING, "abs", (char *)&parms.abs, "Abstract regular expression"},
  81.     {OPT_STRING, "owner", (char *)&parms.owner, "Userid of owner "},
  82.     {OPT_STRING, "group", (char *)&parms.group, "Group name"},
  83.     {OPT_TRUE, "sync", (char *)&parms.sync, "Sync data to tape"},
  84.     {OPT_STRING, "mail", (char *)&parms.mail, "Mail address"},
  85.     {OPT_CONSTANT(INT_MAX), "R", (char *)&parms.recurse, "List directories recursively"},
  86.     {OPT_TRUE, "moddate", (char *)&parms.modDate, "Use last-modification date, not archive date"},
  87.     {OPT_INT, "first", (char *)&parms.firstVer, "Item number. See man page."},
  88.     {OPT_INT, "last", (char *)&parms.lastVer, "Item number. See man page."},
  89.     {OPT_TRUE, "all", (char *)&parms.all, "synonym for -first 1 -last -1"},
  90.     {OPT_TRUE, "l", (char *)&parms.lPrintFmt, "Show data in long format. See below."},
  91.     {OPT_TRUE, "i", (char *)&parms.iPrintFmt, "Show buffer Id"},
  92.     {OPT_TRUE, "u", (char *)&parms.uPrintFmt, "Show archive date instead of last-mode date"},
  93.     {OPT_TRUE, "a", (char *)&parms.aPrintFmt, "Show abstract"},
  94.     {OPT_TRUE, "s", (char *)&parms.sPrintFmt, "Show size in 1K blocks"},
  95.     {OPT_TRUE, "g", (char *)&parms.gPrintFmt, "Show group name"},
  96.     {OPT_TRUE, "d", (char *)&parms.dirOnly, "Show directory only"},
  97.     {OPT_TRUE, "raw", (char *)&parms.raw, "Raw output"}
  98. };
  99. int numOptions = sizeof(optionArray) / sizeof(Option);
  100.  
  101.  
  102. /*
  103.  *----------------------------------------------------------------------
  104.  *
  105.  * main --
  106.  *
  107.  *    Main driver for als program.
  108.  *
  109.  * Results:
  110.  *    none.
  111.  *
  112.  * Side effects:
  113.  *    Sends requests across socket to tapestry server.
  114.  *
  115.  *----------------------------------------------------------------------
  116.  */
  117.  
  118. int
  119. main(argc, argv)
  120. int argc;
  121. char *argv[];
  122. {
  123.     int sock;
  124.     T_RespMsgHdr resp;
  125.     char defaultName = '\0';
  126.     char *defaultList = &defaultName;
  127.  
  128. /*    memDbg = fopen("jls.mem", "w"); */
  129.     MEM_CONTROL(8192, memDbg, TRACEMEM+TRACECALLS, 4096);
  130.  
  131.     argc = Opt_Parse(argc, argv, optionArray, numOptions, 0);
  132.  
  133.     CheckOptions(&parms);
  134.  
  135.     sock = Sock_SetupSocket(parms.port, parms.server, 1);
  136.  
  137.     Sock_SendReqHdr(sock, T_CMDLS, 0, parms.mail,  parms.arch, 0);
  138.  
  139.     /* put out query parameters */
  140.     Sock_WriteInteger(sock, parms.firstVer);
  141.     Sock_WriteInteger(sock, parms.lastVer);
  142.     Sock_WriteInteger(sock, parms.firstDate);
  143.     Sock_WriteInteger(sock, parms.lastDate);
  144.     Sock_WriteString(sock, parms.owner, 0);
  145.     Sock_WriteString(sock, parms.group, 0);
  146.     Sock_WriteInteger(sock, parms.modDate);
  147.     Sock_WriteInteger(sock, parms.recurse);
  148.     Sock_WriteString(sock, parms.abs, 0);
  149.  
  150.     /* get ok to continue */
  151.     Sock_ReadRespHdr(sock, &resp);
  152.     if (resp.status != T_SUCCESS) {
  153.     fprintf(stdout,"%s", Utils_MakeErrorMsg(resp.status, resp.errno));
  154.     close(sock);
  155.     exit(-1);
  156.     }
  157.  
  158.     /* put out regular expressions */
  159.     if (argc > 1) {
  160.     SendStrings(--argc, &argv[1], sock);
  161.     } else {
  162.     SendStrings(1, &defaultList, sock);
  163.     }
  164.  
  165.     ReadAndShowFiles(sock, &parms);
  166.  
  167.     Sock_ReadRespHdr(sock, &resp);
  168.     if (resp.status != T_SUCCESS) {
  169.     fprintf(stdout,"%s", Utils_MakeErrorMsg(resp.status, resp.errno));
  170.     }
  171.  
  172.     close(sock);
  173.     MEM_REPORT("jls", ALLROUTINES, SORTBYREQ);
  174.  
  175.     return(0);
  176.  
  177. }
  178.  
  179.  
  180. /*
  181.  *----------------------------------------------------------------------
  182.  *
  183.  * SendStrings --
  184.  *
  185.  *    Send a list of regular expressions
  186.  *
  187.  * Results:
  188.  *    none.
  189.  *
  190.  * Side effects:
  191.  *    Shoves data out the socket.
  192.  *
  193.  *----------------------------------------------------------------------
  194.  */
  195.  
  196. static void
  197. SendStrings(nameCnt, nameList, sock)
  198.     int nameCnt;              /* # strings */
  199.     char **nameList;          /* array of string ptrs */
  200.     int sock;                 /* destination socket */
  201. {
  202.     char *fileList;
  203.     int packedLen;
  204.     char fmt[MAXARG];
  205.     char *fmtPtr;
  206.     int i;
  207.     int base = 0;
  208.     int quantity;
  209.  
  210.     Sock_WriteInteger(sock, nameCnt);
  211.  
  212.     while (base < nameCnt) {
  213.     quantity = (nameCnt-base > MAXARG) ? MAXARG : nameCnt-base;
  214.     for (i=base, fmtPtr=fmt; i<base+quantity; i++) {
  215.         nameList[i] = Utils_MakeFullPath(nameList[i]);
  216.         *fmtPtr++ = 'C';
  217.     }
  218.     *fmtPtr = '\0';
  219.     fileList = Sock_PackData(fmt, nameList+base, &packedLen);
  220.     if (Sock_WriteNBytes(sock, fileList, packedLen) != packedLen) {
  221.         fprintf(stderr,"Failed to write strings to socket: errno %d\n",
  222.             syserr);
  223.     }
  224.     MEM_FREE("main", fileList);
  225.     base += quantity;
  226.     }
  227.  
  228. }
  229.  
  230.  
  231.  
  232. /*
  233.  *----------------------------------------------------------------------
  234.  *
  235.  * ReadAndShowFiles --
  236.  *
  237.  *    Retrieve and display all the filenames
  238.  *
  239.  * Results:
  240.  *    none.
  241.  *
  242.  * Side effects:
  243.  *    none.
  244.  *
  245.  *----------------------------------------------------------------------
  246.  */
  247.  
  248. static void
  249. ReadAndShowFiles(sock, parmsPtr)
  250.     int sock;                 /* incoming socket */
  251.     Parms *parmsPtr;          /* parameter block */
  252. {
  253.     char workingDir[T_MAXPATHLEN];
  254.     int workingDirLen;
  255.     static T_FileStat statInfo;
  256.  
  257.     Utils_GetWorkingDir(workingDir, &workingDirLen);
  258.  
  259.     while (Sock_ReadFileStat(sock, &statInfo, 1) == T_SUCCESS) {
  260.     if (!*statInfo.fileName) {
  261.         return;
  262.     }
  263.     if (parmsPtr->raw) {
  264.         FormatRaw(&statInfo);
  265.     } else {
  266.         FormatRegular(&statInfo, parmsPtr, workingDir, workingDirLen);
  267.     }
  268.     Utils_FreeFileStat(&statInfo, 0);
  269.     }
  270.  
  271.     printf("Got error trying to read T_FileStat\n");
  272.  
  273. }
  274.  
  275.  
  276.  
  277. /*
  278.  *----------------------------------------------------------------------
  279.  *
  280.  * FormatRegular --
  281.  *
  282.  *    Format output according to command line flags.
  283.  *
  284.  * Results:
  285.  *    none.
  286.  *
  287.  * Side effects:
  288.  *    Dumps file metadata to stdout
  289.  *
  290.  *----------------------------------------------------------------------
  291.  */
  292.  
  293. static void
  294. FormatRegular(statInfoPtr, parmsPtr, workingDir, workingDirLen)
  295.     T_FileStat *statInfoPtr;
  296.     Parms *parmsPtr;
  297.     char *workingDir;
  298.     int workingDirLen;
  299. {
  300.     char datePtr[26];
  301.     char *filePtr;
  302.     static char cwd[2] = ".";
  303.  
  304.     if (parmsPtr->iPrintFmt) {
  305.     /* filemark is the id for the header. data is in filemark+1 */
  306.     fprintf(stdout,"%6d %6d %6d ",
  307.         statInfoPtr->tBufId, statInfoPtr->volId,
  308.         statInfoPtr->filemark+1);
  309.     }
  310.     if (parmsPtr->sPrintFmt) {
  311.     fprintf(stdout,"%6d ", (statInfoPtr->size+1024)>>10);
  312.     }
  313.     if (strncmp(workingDir, statInfoPtr->fileName, workingDirLen) == 0){
  314.     if (workingDirLen == 1) {
  315.         filePtr = statInfoPtr->fileName + 1;
  316.     } else if (strlen(statInfoPtr->fileName) > workingDirLen) {
  317.         filePtr = statInfoPtr->fileName + workingDirLen + 1;
  318.     } else {
  319.         filePtr = cwd;
  320.     }
  321.     } else {
  322.     filePtr = statInfoPtr->fileName;
  323.     }
  324.     if (parmsPtr->lPrintFmt) {
  325.     if (parmsPtr->uPrintFmt) {
  326.         strcpy(datePtr,Time_CvtToString(&statInfoPtr->vtime));
  327.     } else {
  328.         strcpy(datePtr,Time_CvtToString(&statInfoPtr->mtime));
  329.     }
  330.     fprintf(stdout,"%s %8s",
  331.         CvtModeToString(statInfoPtr->mode), statInfoPtr->uname);
  332.     if (parmsPtr->gPrintFmt) {
  333.         fprintf(stdout," %8s", statInfoPtr->gname);
  334.     }
  335.     fprintf(stdout," %8d %s %s", statInfoPtr->size, datePtr, filePtr);
  336.     if (S_ISALNK(statInfoPtr->mode)) {
  337.         fprintf(stdout," -> %s", statInfoPtr->linkName);
  338.     }
  339.     } else {
  340.     fprintf(stdout,"%s", filePtr);
  341.     }
  342.     if (parmsPtr->aPrintFmt) {
  343.     fprintf(stdout, "\n\t%s\n", statInfoPtr->abstract);
  344.     } else {
  345.     fputc('\n', stdout);
  346.     }
  347.  
  348. }
  349.  
  350.  
  351.  
  352. /*
  353.  *----------------------------------------------------------------------
  354.  *
  355.  * FormatRaw --
  356.  *
  357.  *    Dump the T_FileStat contents 
  358.  *
  359.  * Results:
  360.  *    none.
  361.  *
  362.  * Side effects:
  363.  *    none.
  364.  *
  365.  *----------------------------------------------------------------------
  366.  */
  367.  
  368. static void
  369. FormatRaw(statInfoPtr)
  370.     T_FileStat *statInfoPtr;
  371. {
  372.     static char metaChars[] = "\"";
  373.     char dateSpace[26];
  374.  
  375.     strcpy(dateSpace,Time_CvtToString(&statInfoPtr->mtime));
  376.     *(dateSpace+3) = '\0';
  377.     *(dateSpace+6) = '\0';
  378.  
  379.     printf("%s|%s|%s|%d|%s|%s|%s|%s|%s|%s|%s\n",
  380.         CvtModeToString(statInfoPtr->mode),
  381.         Str_Quote(statInfoPtr->uname, metaChars),
  382.         Str_Quote(statInfoPtr->gname, metaChars),
  383.         statInfoPtr->size,
  384.         dateSpace,
  385.         dateSpace+4,
  386.         dateSpace+7,
  387.         Str_Quote(statInfoPtr->fileName, metaChars),
  388.         (*statInfoPtr->linkName) ? "->" : "", 
  389.         Str_Quote(statInfoPtr->linkName, metaChars),
  390.         statInfoPtr->abstract);
  391. /*
  392.     printf("%d,%d,%d,%d,%d,%s,%d,%d\n",
  393.         Str_Quote(statInfoPtr->gname, metaChars),
  394.         Str_Quote(statInfoPtr->abstract, metaChars),
  395.         Time_CvtToString(&statInfoPtr->atime),
  396.         statInfoPtr->filemark,
  397.         statInfoPtr->tBufId,
  398.         statInfoPtr->mode,
  399.         statInfoPtr->uid,
  400.         statInfoPtr->gid,
  401.         Time_CvtToString(&statInfoPtr->mtime),
  402.         statInfoPtr->volId;
  403.         statInfoPtr->rdev);
  404. */
  405. }
  406.  
  407.  
  408.  
  409. /*
  410.  *----------------------------------------------------------------------
  411.  *
  412.  * CvtModeToString --
  413.  *
  414.  *    Make file's mode value printable
  415.  *
  416.  * Results:
  417.  *    none.
  418.  *
  419.  * Side effects:
  420.  *    none.
  421.  *
  422.  *----------------------------------------------------------------------
  423.  */
  424.  
  425. static char *
  426. CvtModeToString(mode)
  427.     int mode;
  428. {
  429.     int type;
  430.     static char modeStr[11];
  431.     static char *modeArray[] = {
  432.     "---",    "--x",    "-w-",    "-wx",
  433.     "r--",    "r-x",    "rw-",    "rwx"
  434.     };
  435.  
  436.     type = mode & S_IFMT;
  437.     if (type == S_IFDIR) {
  438.     modeStr[0] = 'd';
  439.     } else if (type == S_IFCHR) {
  440.     modeStr[0] = 'c';
  441.     } else if (type == S_IFLNK) {
  442.     modeStr[0] = 'l';
  443.     } else if (type == S_IFBLK) {
  444.     modeStr[0] = 'b';
  445.     } else if (type == S_IFRLNK) {
  446.     modeStr[0] = 'r';
  447.     } else {
  448.     modeStr[0] = '-';
  449.     }
  450.  
  451.     strcpy(modeStr+1, modeArray[(mode>>6) & 7]);
  452.     strcpy(modeStr+4, modeArray[(mode>>3) & 7]);
  453.     strcpy(modeStr+7, modeArray[(mode) & 7]);
  454.  
  455.     return modeStr;
  456. }
  457.  
  458.  
  459.  
  460. /*
  461.  *----------------------------------------------------------------------
  462.  *
  463.  * CheckOptions -- 
  464.  *
  465.  *    Make sure command line options look reasonable
  466.  *
  467.  * Results:
  468.  *    none.
  469.  *
  470.  * Side effects:
  471.  *    none.
  472.  *
  473.  *----------------------------------------------------------------------
  474.  */
  475.  
  476. static void
  477. CheckOptions(parmsPtr)
  478.     Parms *parmsPtr;
  479. {
  480.     struct timeb timeB1;
  481.     struct timeb timeB2;
  482.     char *envPtr;
  483.  
  484.     if ((!*parmsPtr->arch) &&
  485.     ((envPtr=getenv(ENV_ARCHIVE_VAR)) != (char *)NULL)) {
  486.     parmsPtr->arch = envPtr;
  487.     }
  488.     if ((*parmsPtr->arch) &&
  489.     (Utils_CheckName(parmsPtr->arch, 1) == T_FAILURE)) {
  490.     sprintf(printBuf,
  491.         "Bad archive name: '%s'.\nUse -arch or set %s environment variable.\n",
  492.         parmsPtr->arch, ENV_ARCHIVE_VAR);
  493.     Utils_Bailout(printBuf, BAIL_PRINT);
  494.     }
  495.     if ((!*parmsPtr->server) &&
  496.     ((parmsPtr->server=getenv(ENV_SERVER_VAR)) == (char *)NULL)) {
  497.     parmsPtr->server = DEF_SERVER;
  498.     }
  499.     if (Utils_CheckName(parmsPtr->server, 1) == T_FAILURE) {
  500.     sprintf(printBuf,
  501.         "Bad server name: '%s'.\nUse -server or set %s environment variable.\n",
  502.         parmsPtr->server, ENV_SERVER_VAR);
  503.     Utils_Bailout(printBuf, BAIL_PRINT);
  504.     }
  505.     if (parmsPtr->port == -1) {
  506.     if ((envPtr=getenv(ENV_PORT_VAR)) == (char *)NULL) {
  507.         parmsPtr->port = DEF_PORT;
  508.     } else {
  509.         Utils_CvtInteger(envPtr, 1, SHRT_MAX, &parmsPtr->port);
  510.     }
  511.     }
  512.     if ((parmsPtr->port < 1) || (parmsPtr->port > SHRT_MAX)) {
  513.     sprintf(printBuf,
  514.         "Bad port number %d.\nUse -port or set %s environment variable\n",
  515.         parmsPtr->port, ENV_PORT_VAR);
  516.     Utils_Bailout(printBuf, BAIL_PRINT);
  517.     }
  518.     if ((*parmsPtr->mail) && 
  519.     (Utils_CheckName(parmsPtr->mail, 1) != T_SUCCESS)) {
  520.     sprintf(printBuf, "Bad mail address: '%s'\n", parmsPtr->mail);
  521.     Utils_Bailout(printBuf, BAIL_PRINT);
  522.     }
  523.     if ((strcmp(parmsPtr->owner, DEF_OWNER) != 0) &&
  524.     (Utils_GetUidByLogin(parmsPtr->owner) == T_FAILURE)) {
  525.     sprintf(printBuf, "Don't know user '%s'. Continue? [y/n] ",
  526.         parmsPtr->owner);
  527.         if (!Utils_GetOk(printBuf)) {
  528.         exit(-1);
  529.     }
  530.     }
  531.     if ((strcmp(parmsPtr->group, DEF_GROUP) != 0) &&
  532.     (Utils_GetGidByGroup(parmsPtr->group) == T_FAILURE)) {
  533.     sprintf(printBuf, "Don't know group '%s'. Continue? [y/n] ",
  534.         parmsPtr->group);
  535.         if (!Utils_GetOk(printBuf)) {
  536.         exit(-1);
  537.     }
  538.     }
  539.     if ((*parmsPtr->asof) && (*parmsPtr->since)) {
  540.     Utils_Bailout("Conflicting parameters: -asof -since\n", BAIL_PRINT);
  541.     }
  542.     if (*parmsPtr->asof) {
  543.     if (getindate(parmsPtr->asof, &timeB1) != T_SUCCESS) {
  544.         Utils_Bailout("Need date in format: 20-Mar-1980:10:20:0",
  545.               BAIL_PRINT);
  546.     }
  547.     parmsPtr->firstDate = 0;
  548.     parmsPtr->lastDate = timeB1.time;
  549.     }
  550.     if (*parmsPtr->since) {
  551.     if (getindate(parmsPtr->since, &timeB1) != T_SUCCESS) {
  552.         Utils_Bailout("Need date in format: 20-Mar-1980:10:20:0",
  553.               BAIL_PRINT);
  554.     }
  555.     parmsPtr->firstDate = timeB1.time;
  556.     parmsPtr->lastDate = Time_GetCurDate();
  557.     }
  558.     if (*parmsPtr->range) {
  559.     if (getindatepair(parmsPtr->range, &timeB1, &timeB2) !=
  560.         T_SUCCESS) {
  561.         Utils_Bailout("Need date pair in format: date,date2", BAIL_PRINT);
  562.     }
  563.     parmsPtr->firstDate = timeB1.time;
  564.     parmsPtr->lastDate  = timeB2.time;
  565.     }
  566.     if (parmsPtr->all) {
  567.     if ((parms.firstVer != DEF_FIRSTVER) ||
  568.         (parms.lastVer != DEF_LASTVER)) {
  569.         Utils_Bailout("Don't mix -all option with -first or -last",
  570.               BAIL_PRINT);
  571.     } else {
  572.         parms.firstVer = 1;
  573.         parms.lastVer = -1;
  574.     }
  575.     }
  576.     if ((parms.firstVer == 0) || (parms.lastVer == 0)) {
  577.     Utils_Bailout("Version number cannot be 0.\n", BAIL_PRINT);
  578.     }
  579.     if (parmsPtr->dirOnly) {
  580.     if (parmsPtr->recurse > 1) {
  581.         Utils_Bailout("The -recurse and -d options are mutually exclusive.\n",
  582.             BAIL_PRINT);
  583.     }
  584.     parmsPtr->recurse = 0;
  585.     }
  586.     if ((parmsPtr->raw) &&
  587.     (parmsPtr->lPrintFmt | parmsPtr->iPrintFmt |
  588.      parmsPtr->uPrintFmt | parmsPtr->aPrintFmt)) {
  589.     Utils_Bailout("The -raw option doesn't mix with -a -l -i -u.\n",
  590.               BAIL_PRINT);
  591.     }
  592. }
  593.